package com.zengdada.authority.controller;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.zengdada.authority.config.security.intercept.AuthorityUtil;
import com.zengdada.authority.config.security.intercept.MyFilterInvocationSecurityMetadataSource;
import com.zengdada.authority.exception.RoutineException;
import com.zengdada.authority.model.AppRole;
import com.zengdada.authority.model.AppUser;
import com.zengdada.authority.model.AppUserRoleRel;
import com.zengdada.authority.service.*;
import com.zengdada.authority.service.impl.AppRoleAuthorityServiceImpl;
import com.zengdada.authority.utils.CommonUtils;
import com.zengdada.authority.utils.JsonMessage;
import com.zengdada.authority.utils.mapper.Page;
import com.zengdada.authority.utils.mapper.Sort;
import com.zengdada.authority.utils.where.Where;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;


import java.util.*;
import java.util.stream.Collectors;

import static com.zengdada.authority.utils.JsonMessage.fail;
import static com.zengdada.authority.utils.JsonMessage.success;

/**
 * @Auther: 12614
 * @Contact: 1261438511@qq.com
 * @Date: 2018/12/4 22:02
 * @Description:
 */
@Controller
@RequestMapping("/authority/role")
public class AppRoleAuthorityController {

    @Autowired
    AuthorityUtil authorityUtil;

    @Autowired
    @Qualifier("appPowerAuthorityServiceImpl")
    AppPowerAuthorityService appPowerAuthorityService;

    @Autowired
    @Qualifier("appRoleAuthorityServiceImpl")
    AppRoleAuthorityService appRoleAuthorityService;

    @Autowired
    @Qualifier("appUserAuthorityServiceImpl")
    AppUserAuthorityService appUserAuthorityService;

    @Autowired
    @Qualifier("appUserRoleRelAuthorityServiceImpl")
    AppUserRoleRelAuthorityService appUserRoleRelAuthorityService;

    @Autowired
    @Qualifier("appPowerRoleRelAuthorityServiceImpl")
    AppPowerRoleRelAuthorityService appPowerRoleRelAuthorityService;

    @Autowired
    private MyFilterInvocationSecurityMetadataSource securityMetadataSource;

    @GetMapping("/page.html")
    public String page() {
        return "authority/role/role";
    }

    @GetMapping("/config.html")
    public String config() {
        return "authority/role/role_config";
    }

    @RequestMapping(value = "/role_tree.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage roleTree() {
        try {
            return success(appRoleAuthorityService.getRoleOrDepartmentTree(Collections.singletonList(AppRoleAuthorityServiceImpl.TYPE_ROLE)));
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }

    @RequestMapping(value = "/list.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage list(@RequestParam(value = "id", defaultValue = "") String id, String searchs, Page page, Sort sort) {
        try {
            List<Where> params = new ArrayList<>();
            Where where = new Where(Where.Formula.AND, params);
            try {
                params.add(Where.formJsonString(StringEscapeUtils.unescapeHtml4(searchs)));
            } catch (Exception e) {
                throw new RoutineException("查询条件解析失败：" + e.getMessage());
            }
            Where search = new Where();
            if ("".equals(id)) {
                search.setField("id");
                search.setFormulaE(Where.Formula.IN);
                List<String> pids = appRoleAuthorityService.getRoleOrDepartmentTree(Collections.singletonList(AppRoleAuthorityServiceImpl.TYPE_ROLE)).stream().map(i -> (String) i.get("id")).collect(Collectors.toList());
                search.setValue(JSON.toJSONString(pids));
            } else {
                search.setField("parentId");
                search.setFormulaE(Where.Formula.EQUAL);
                search.setValue(id);
            }
            params.add(search);
            PageInfo<Map<String, Object>> appRolePageInfo = appRoleAuthorityService.selectDetailedPageInfoByParam(where, page, sort);
            return success(appRolePageInfo.getList(), appRolePageInfo.getTotal());
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }

    @RequestMapping(value = "/detailed.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage detailed(@RequestParam(value = "id", defaultValue = "") String id) {
        try {
            AppRole appRole = appRoleAuthorityService.selectById(id);
            if (appRole == null) throw new RoutineException("未查询到相关信息");
            return success(appRole);
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }

    @RequestMapping(value = "/del.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage del(@RequestParam(value = "id", defaultValue = "") String id) {
        try {
            AppRole appRole = appRoleAuthorityService.selectById(id);
            if (appRole == null) throw new RoutineException("没有找到相关信息！！");
            if (!havePower(appRole.getId(), appRole.getParentId(), true))
                throw new RoutineException("你没有权限修改当前数据！！");
            if (appRoleAuthorityService.deleteById(id) == 0) throw new RoutineException("没有删除任何数据！！");
            securityMetadataSource.initOrUpdateMap();
            return success();
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }

    @RequestMapping(value = {"/add.do"}, method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage add(AppRole appRole) {
        try {
            AppUser user = authorityUtil.getLoginUser();
            if (StringUtils.isBlank(appRole.getId())) {
                if (!havePower(null, appRole.getParentId(), true))
                    throw new RoutineException("你没有权限修改当前数据！！");
                appRole.setModifyUser(user.getId());
                CommonUtils.reflectObjectTransString(appRole, false);
                if (appRoleAuthorityService.add(appRole) == 0) throw new RoutineException("新增失败！！");
            } else {
                AppRole appRole1 = appRoleAuthorityService.selectById(appRole.getId());
                if (appRole1 == null) throw new RoutineException("没有找到相关信息！！");
                if (!havePower(appRole1.getId(), appRole.getParentId(), true))
                    throw new RoutineException("你没有权限修改当前数据！！");
                appRole.setModifyUser(user.getId());
                appRole.setModifyTime(new Date());
                if (appRoleAuthorityService.updateById(appRole) == 0) throw new RoutineException("没有修改任何数据！！");
            }
            return success();
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }


    //-----------角色-权限 角色-用户 配置 ---------------
    //-----------角色-权限 配置 ---------------

    @RequestMapping(value = "/role_users.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage roleUsers(String roleId, String searchs,
                                 @RequestParam(value = "type", defaultValue = "1") int type, Sort sort, Page page) {
        try {
            if (StringUtils.isBlank(roleId)) throw new RoutineException("请选择左侧节点");
            PageInfo<AppUser> list = appUserAuthorityService.selectPageInfoByRoleId(roleId, type == 1, searchs, page, sort);
            return success(list.getList(), (int) list.getTotal());
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }

    @RequestMapping(value = "/change_user_rel.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage changeUserRel(String roleId, String userIds, String type) {
        try {
            if (roleId == null || userIds == null || type == null)
                throw new RuntimeException("参数错误！！");
            if (!havePower(roleId, null, false)) throw new RoutineException("没有操作当前数据权限！！");
            List<String> userIdList = Arrays.asList(userIds.split(","));
            userIdList.forEach(userId -> {
                AppUserRoleRel appUserRoleRel = new AppUserRoleRel();
                appUserRoleRel.setAppUserId(userId);
                appUserRoleRel.setAppRoleId(roleId);
                if ("binding".equals(type)) {
                    appUserRoleRel.setCreateTime(new Date());
                    appUserRoleRelAuthorityService.add(appUserRoleRel);
                } else if ("untie".equals(type)) {
                    appUserRoleRelAuthorityService.deleteById(appUserRoleRel);
                }
            });
//            appUserRoleRelAuthorityService.changeRel(user, roleId, userIds, type);
//            // 修改全局变量中的权限版本号 使用户调用时去数据库更新自己的角色
            securityMetadataSource.initOrUpdateMap();
            return success();
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }

    //---------角色-权限 配置-----------

    @RequestMapping(value = "/power_tree.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage powerTree(String roleId) {
        try {
//            AppUser user = authorityUtil.getLoginUser();
            List<Map<String, Object>> list = appPowerAuthorityService.getPowerTreeByRole(roleId);
            return success(list);
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }

    @RequestMapping(value = "/change_power_rel.do", method = RequestMethod.POST)
    @ResponseBody
    public JsonMessage changePowerRel(String roleId, @RequestParam(defaultValue = "[]") String powerIds) {
        try {
            if (!havePower(roleId, null, false)) throw new RoutineException("没有操作当前数据权限！！");
            int num = appPowerRoleRelAuthorityService.changeByRoleId(roleId, powerIds);
            if (num > 0) securityMetadataSource.initOrUpdateMap();
            return success();
        } catch (Exception e) {
            return fail(e.getMessage());
        }
    }


    /**
     * 判断是否有权限 （用户是否含有当前权限或子权限，不能是当前的初级（isFirst）权限）
     *
     * @param roleId
     * @return
     */
    private boolean havePower(String roleId, String parentId, boolean isSon) {
        boolean havePower = false;
        if (authorityUtil.isSuperAdministrator()) return true;
        List<Map<String, Object>> roles = appRoleAuthorityService.getRoleOrDepartment(Collections.singletonList(AppRoleAuthorityServiceImpl.TYPE_ROLE));
        if (!havePower) {
            List<Map<String, Object>> roleTree = CommonUtils.generateTreeMapCurrency(roles, "id", "parentId", "children");
            for (Map<String, Object> role : roles) {
                if (role.get("id").equals(roleId)) {
                    havePower = true;
                    break;
                }
            }
            if (havePower)
                for (Map<String, Object> role : roleTree) {
                    if (role.get("id").equals(roleId) && Boolean.valueOf(role.get("isFirst").toString())) {
                        havePower = false;
                        break;
                    }
                }
        }

        if (isSon && !havePower) { // 没有权限 判断当前权限是不是 拥有的权限的 儿子
            if (parentId == null) return false;
            for (Map<String, Object> role : roles) {
                if (role.get("id").equals(parentId)) {
                    havePower = true;
                    break;
                }
            }
        }
        return havePower;
    }

}
